// The key observation is that you can alwayse choose the shortest tree and make other trees the same height as it. Thus, n-1 is the answer if there is no better choice. Otherwise, the answer must pass through two trees. We can do brute force to test this condition.
// One trick needs to be learned is that when you calculating the slope of a line, there is division operations, which is not precise. Such operations could be transformed into multiplications, but be aware of overflow!
 
 #include <vector>
 #include <list>
 #include <map>
 #include <set>
 #include <deque>
 #include <queue>
 #include <stack>
 #include <bitset>
 #include <algorithm>
 #include <functional>
 #include <numeric>
 #include <utility>
 #include <sstream>
 #include <iostream>
 #include <iomanip>
 #include <cstdio>
 #include <cmath>
 #include <cstdlib>
 #include <ctime>

 using namespace std;

 typedef long long ll;
 typedef vector<int> VI;

 #define INF 1<<30

 class TimeTravellingGardener {
 public:
     int determineUsage(vector <int>, vector <int>);
 };

 int TimeTravellingGardener::determineUsage(vector <int> distance, vector <int> height) {
     VI cum;
     cum.push_back(0);
     for(int i = 0; i < distance.size(); ++i)
         cum.push_back(cum.back()+distance[i]);
    
     int n = height.size();
     int ans = n-1;
     for(int i = 0; i < n; ++i)
         for(int j = i+1; j < n; ++j)
         {
             int k = 0;
             int cnt = 0;
             for(; k < n; ++k)
                 if(k != i && k != j)
                 {
                     int t = (height[j]-height[i])*cum[k] + height[i]*(cum[j]-cum[i]) - cum[i]*(height[j]-height[i]);
                     if(t < 0 || height[k]*(cum[j]-cum[i]) < t)
                         break;
                     if(height[k]*(cum[j]-cum[i]) > t) ++cnt;
                 }
             if(k == n)
                 ans = min(ans, cnt);
         }
        
     return ans;        
 }